using System.Reactive;
using System.Reactive.Linq;
using Avalonia.Threading;
using Microsoft.Extensions.DependencyInjection;
using NexusMods.Abstractions.NexusModsLibrary.Models;
using NexusMods.App.UI.Controls.Navigation;
using NexusMods.App.UI.Helpers;
using NexusMods.App.UI.Pages.CollectionDownload;
using NexusMods.App.UI.Resources;
using NexusMods.App.UI.Windows;
using NexusMods.App.UI.WorkspaceSystem;
using NexusMods.Collections;
using NexusMods.MnemonicDB.Abstractions;
using NexusMods.UI.Sdk;
using NexusMods.UI.Sdk.Icons;
using ReactiveUI;

namespace NexusMods.App.UI.LeftMenu.Items;

public class CollectionRevisionLeftMenuItemViewModel : LeftMenuItemWithRightIconViewModel
{
    private readonly CollectionRevisionMetadataId _collectionRevisionMetadataId;
    private readonly CollectionDownloader _collectionDownloader;
    private readonly IWindowNotificationService _notificationService;
    private readonly IWindowManager _windowManager;
    private readonly IConnection _connection;
    private readonly IWorkspaceController _workspaceController;

    public CollectionRevisionLeftMenuItemViewModel(
        IWorkspaceController workspaceController,
        WorkspaceId workspaceId,
        PageData pageData,
        CollectionRevisionMetadata.ReadOnly revision,
        IServiceProvider serviceProvider) : base(workspaceController, workspaceId, pageData)
    {
        _workspaceController = workspaceController;
        _collectionRevisionMetadataId = revision;
        _collectionDownloader = serviceProvider.GetRequiredService<CollectionDownloader>();
        _notificationService = serviceProvider.GetRequiredService<IWindowNotificationService>();
        _windowManager = serviceProvider.GetRequiredService<IWindowManager>();
        _connection = serviceProvider.GetRequiredService<IConnection>();

        AdditionalContextMenuItems =
        [
            CreateDeleteContextMenuItem(),
        ];
    }

    private IContextMenuItem CreateDeleteContextMenuItem()
    {
        var deleteCommand = CreateDeleteCommand();
        
        return new ContextMenuItem
        {
            Header = Language.CollectionDownloadView_Menu_DeleteCollectionRevision,
            Icon = IconValues.DeleteOutline,
            Command = deleteCommand,
            IsVisible = true,
            Styling = ContextMenuItemStyling.Critical,
        };
    }
    
    private ReactiveCommand<Unit, Unit> CreateDeleteCommand()
    {
        // Non-installed collection revisions can always be deleted
        var canExecute = Observable.Return(true);

        return ReactiveCommand.CreateFromTask(async () =>
        {
            var revision = CollectionRevisionMetadata.Load(_connection.Db, _collectionRevisionMetadataId);
            
            var confirmed = await CollectionDeleteHelpers.ShowDeleteConfirmationDialogAsync(
                revision.Collection.Name, _windowManager);
            
            if (!confirmed)
                return;

            try
            {
                await _collectionDownloader.DeleteRevision(_collectionRevisionMetadataId);
                _notificationService.ShowToast(
                    Language.ToastNotification_Collection_removed,
                    ToastNotificationVariant.Success
                );

                // Navigate away from the deleted revision page to default new tab
                await Dispatcher.UIThread.InvokeAsync(() =>
                    _workspaceController.ReplacePages<CollectionDownloadPageContext>(
                    context => context.CollectionRevisionMetadataId == _collectionRevisionMetadataId)
                );
            }
            catch (Exception ex)
            {
                _notificationService.ShowToast(
                    $"Failed to delete collection: {ex.Message}",
                    ToastNotificationVariant.Failure
                );
            }
        }, canExecute: canExecute);
    }
}
